import { mapYearToLandscapeZ, framer } from '@src/utils/utils'
import __util from '@src/events/__util'

export default function mixinTick (Incident) {
  /**
   *
   * @param t
   * @param el
   * @param secondTick: 第二个记号
   */
  Incident.prototype.tick = function(t, el, secondTick) {
    const { $scope, $camera, scene, camera } = this
    const cameraMinZ = mapYearToLandscapeZ(-2e6) + 40;
    const cameraMaxZ = mapYearToLandscapeZ(2021) + 40;
    let { introLength, introTime, cameraY, cameraZMotion, cameraZTarget, cameraXOffset, cameraYOffset } = $camera
    let introState = $scope.introState = 3 // $scope.introState;
    var time = 0

    if (!this.$objects) {
      this.renderer.clear();
      window.requestAnimationFrame(this.tick.bind(this));
      return;
    }

    if (this.$camera.introTime > 3000 && this.audioManager) {
      // this.audioManager.start();
    }

    // console.log(' --------', introTime, introLength);

    /**
     * introTime < 14000
     * 出厂动画
     * 时间轴布点动画
     */
    if (introTime < introLength + 16) {
      // 大于 0
      /**
       * 前 13000 - 3000 时间，取0
       * introTime = 0
       * @type {number}
       */
      introTime = Math.max(0, introTime - (introLength - 3000));

      /**
       * cameraY 大于零的值
       *
       * Math.max(0, 1 - introTime / 3000)
       * -> 0 ~1
       * introTime 越大 返回值 越小
       *
       * Math.pow(x, y)
       * 求 x 的 y 次方
       */
      this.camera.position.y = Math.max(cameraY, cameraY + 40 * Math.pow(Math.max(0, 1 - introTime / 3000), 3.0));

      this.camera.position.z = (mapYearToLandscapeZ(2021)
        + 28
        + -800 * Math.max(0, 1-Math.pow(introTime / 3000, 2))
      );

      this.camera.target.x = 0;
      this.camera.target.y = camera.position.y + 40 * (1 - introTime / 3000) - 10;
      this.camera.target.z = camera.position.z - 50;

      // console.log(this.$camera.introTime, camera.target.y)
      this.lines.position.z = this.camera.position.z;

      // 相机指向的目标点
      this.camera.lookAt(camera.target);

      // 修改相机位置
      // if (introState >= 2) {
        this.$camera.introTime += 16;

        // console.log(this.$camera.introTime, introLength, introState)
      // }

      if (this.introBlobs) {
        this.introBlobs.position.copy(camera.target);
        this.introBlobs.lookAt(camera.position);
      }
    }

    this.camera.position.z += cameraZMotion * 0.1;

    if (cameraZMotion > 0 && cameraZMotion < 20) {
      this.$camera.cameraZMotion = cameraZMotion + 0.25;
    } else if (cameraZMotion < 0 && cameraZMotion > -20) {
      this.$camera.cameraZMotion = cameraZMotion - 0.25;
    }

    if (cameraZMotion === 0) {
      if (cameraZTarget && Math.abs(cameraZTarget-camera.position.z) < 0.001) {
        this.$camera.cameraZTarget = null;
      }
      if (cameraZTarget !== null) {
        this.$camera.camera.position.z += (cameraZTarget - camera.position.z) * 0.05;
      }
    }

    this.cameraZMotion = cameraZMotion;
    this.cameraZTarget = cameraZTarget;

    /**
     * introTime > 14000 后
     * 点 从开始，到出现动画结束后
     */
    if (introTime >= introLength + 16) {
      this.linesPlane.visible = false;

      this.camera.position.z += this.cameraVelocity.z;

      if (Math.abs(this.cameraVelocity.z) < 1) {
        this.cameraVelocity.z *= 0.9;
      } else {
        this.cameraVelocity.z *= 0.95;
      }

      if (Math.abs(this.cameraVelocity.z) < 0.01) {
        this.cameraVelocity.z = 0;
      }

      this.$camera.cameraXOffset = cameraXOffset + this.cameraVelocity.x;
      if (cameraXOffset > 1) this.$camera.cameraXOffset = 1;
      if (cameraXOffset < -1) this.$camera.cameraXOffset = -1;
      this.cameraVelocity.x *= 0.9;

      this.camera.position.x += (cameraXOffset * 10 - camera.position.x) * 0.05;
      this.camera.position.y += (cameraY + 8 + cameraYOffset * 3 - camera.position.y) * 0.05;

      this.camera.target.x += (Math.sin(cameraXOffset * 0.5) * 30 - camera.target.x) * 0.1;
      this.camera.target.y += (cameraY + 8 - 20 + cameraYOffset * 5 - camera.target.y) * 0.1;
      this.camera.target.z = camera.position.z - Math.cos(cameraXOffset * 0.5) * 50;

      this.camera.lookAt(camera.target);

      this.camera.updateProjectionMatrix();
      this.camera.updateMatrix();

      if (this.labels) {
        this.labels.visible = true;
      }

      if (this.toolBar3D) {
        this.toolBar3D.visible = true;
      }

      this.labels.position.z = camera.position.z - 25;
      this.toolBar3D.position.z = camera.position.z - 25;

      this.lines.position.z = this.toolBar3D.position.z;

      if (camera.position.z > cameraMaxZ) {
        this.camera.position.z += (cameraMaxZ - camera.position.z) * 0.1;
      } else if (camera.position.z < cameraMinZ) {
        this.camera.position.z += (cameraMinZ - camera.position.z) * 0.1;
      }

      if (cameraZTarget > cameraMaxZ) {
        this.$camera.cameraZTarget += (cameraMaxZ - cameraZTarget) * 0.1;
      } else if (cameraZTarget < cameraMinZ) {
        this.$camera.cameraZTarget += (cameraMinZ - cameraZTarget) * 0.1;
      }

      if ($scope.hoverInfoObject) {
        this.scene.updateMatrixWorld();
        this.linesPlane.updateMatrixWorld();
        this.$scope.hoverInfoObject.hoverConnectionTarget.updateMatrixWorld();
        __util.moveToScreenCoords(
          $scope.hoverInfoObject.hoverConnectionTarget,
          this,
        );
      }
    }

    this.landscapeShaderMaterial.uniforms.time.value += 0.016;

    scene.tick();

    // console.log(this.$option.frameElapsed)

    if (this.$option.frameElapsed > 25 && (!secondTick || secondTick < 4)) {
      this.$option.frameElapsed -= 25;

      this.tick(time, undefined, (secondTick || 0) + 1);
    } else {
      time = framer();
      // console.log(this.$option.frameElapsed, this.$option.lastFrameTime)
      const toolbar = __util.findToolbarUnderEvent(this.mouseCurrent, this)
      const objectUnder = __util.findObjectUnderEvent(this.mouseCurrent, this)

      this.$option.frameElapsed = time - this.$option.lastFrameTime;
      this.$option.lastFrameTime = time;
      this.render();

      this.$overlays.style.cursor = ( toolbar || objectUnder ) ? 'pointer' : 'default'
      window.requestAnimationFrame(this.tick.bind(this));
    }
  };


  Incident.prototype.blobTick = function(self) {
    const { $scope, toolBar3D, $camera } = self
    var blob = this;

    var largerZThanToolbar = (this.position.z > toolBar3D.position.z);

    if (this.largerZThanToolbar === null) {
      this.largerZThanToolbar = largerZThanToolbar;
    }

    /*if (this.largerZThanToolbar !== largerZThanToolbar) {
      this.largerZThanToolbar = largerZThanToolbar;
      if (this.audioManager && $camera.introTime > $camera.introLength && !this.disabled) {
        if (this.soundIndex === undefined) {
          this.soundIndex = -4 * this.position.y;
        }
        this.audioManager.playSoundEffect(this.soundIndex);
      }
    }*/

    var idx = this.parent.children.indexOf(blob);
    var t = (Date.now() / (300 * (1 + idx % 3)) + 4.8 * idx);
    if ($scope.__bullet && $scope.__bullet === this.objectData.bullet) {
      if (this.disabled) {
        this.material.colorChangeDelay = Math.max(0, -Math.floor((this.position.z - self.camera.position.z)/10 + 3 * Math.random()));
        this.material.color.setHex( this.originalColor );
        this.disabled = false;
      }
    } else {
      if (
        ($scope.selectedGeography && this.objectData.cultureName !== $scope.selectedGeography) ||
        ($scope.category && this.objectData.categoryName !== $scope.category)
      ) {
        if (this.originalColor === undefined) {
          this.originalColor = this.material.color.getHex();
        }

        if (!this.disabled) {
          this.material.colorChangeDelay = Math.max(0, -Math.floor((this.position.z - self.camera.position.z)/10 + 3 * Math.random()));
          this.material.color.setHex( 0x7B7E6D );
          this.disabled = true;
        }

      } else if (this.originalColor !== undefined) {
        if (this.disabled) {
          this.material.colorChangeDelay = Math.max(0, -Math.floor((this.position.z - self.camera.position.z)/10 + 3 * Math.random()));
          this.material.color.setHex( this.originalColor );
          this.disabled = false;
        }
      }
    }

    blob.relativePos.x = 0;
    blob.relativePos.y = this.originalPosition.y - this.position.y;
    blob.relativePos.z = 0;

    blob.targetPos.addVectors(this.position, blob.relativePos);

    var posDeltaSpeed = 0.0001;

    if ($camera.introTime < $camera.introLength) {
      if (self.camera.position.z > blob.position.z) {
        blob.targetPos.copy(blob.originalPosition);
      } else {
        blob.targetPos.copy(blob.originalPosition);
        blob.targetPos.y += 40;
      }
      blob.velocity.multiplyScalar(0.7);
      posDeltaSpeed = 0.002;
    }

    blob.posDelta.subVectors(blob.targetPos, blob.position);

    var d = blob.posDelta.length();
    blob.posDelta.multiplyScalar(d * posDeltaSpeed);
    blob.velocity.add(blob.posDelta);

    blob.floatVec.set(Math.sin(1.3*t), Math.cos(t* ((idx % 2) - 0.5)*2), Math.sin(0.7*t));
    blob.floatVec.multiplyScalar(0.0001);
    blob.velocity.add(blob.floatVec);

    if (blob.material.colorChangeDelay === 0) {
      var s;
      if (blob.selected) {
        blob.velocity.multiplyScalar(0);
        s = blob.scale.x + (3*(1.25 * 0.75) - blob.scale.x) * 0.1;
      } else if (blob.connectionSelected) {
        s = blob.scale.x + (3*(1.0 * 0.75) - blob.scale.x) * 0.1;
      } else if (blob.disabled) {
        s = blob.scale.x + (3*(0.5 * 0.5) - blob.scale.x) * 0.1;
      } else if (blob.hovered) {
        s = blob.scale.x + (3*(1.15 * 0.75) - blob.scale.x) * 0.1;
      } else {
        s = blob.scale.x + (3*(0.75 * 0.75) - blob.scale.x) * 0.1;
      }
      blob.scale.set(s,s,s);
    }

    blob.velocity.z = 0;

    blob.position.add(blob.velocity);
    blob.velocity.multiplyScalar(0.95);

    if (this.selected) {
      if (!this.sticksContainer.parent) {
        self.$objects.sticks.add(this.sticksContainer);
        this.sticksContainer.visible = true;
      }
    } else if (this.sticksContainer.parent) {
      this.sticksContainer.parent.remove(this.sticksContainer);
      this.sticksContainer.visible = false;
    }

    if (blob.material.colorChangeDelay === 0) {
      var c0 = blob.material.uniforms.color.value;
      var c1 = blob.material.color;
      blob.material.uniforms.color.value.set(
        c0.x + (c1.r - c0.x) * blob.material.colorChangeSpeed,
        c0.y + (c1.g - c0.y) * blob.material.colorChangeSpeed,
        c0.z + (c1.b - c0.z) * blob.material.colorChangeSpeed
      );
    } else {
      blob.material.colorChangeDelay--;
    }
  };

  Incident.prototype.stickTick = function() {
    var start = this.start.position
    var end = this.end.position

    this.position.set((start.x + end.x) * 0.5, (start.y + end.y) * 0.5, (start.z + end.z) * 0.5);
    this.lookAt(this.start.position);

    var distance = this.start.position.distanceTo(end);

    if (distance === 0) {
      // console.log('something is broken in sticks')
    }
    this.stick.scale.set(0.1, 0.1, distance);

    var c1 = this.start.material.uniforms.color.value;
    this.stick.startColor.r = c1.x;
    this.stick.startColor.g = c1.y;
    this.stick.startColor.b = c1.z;

    var c2 = this.end.material.uniforms.color.value;
    this.stick.endColor.r = c2.x;
    this.stick.endColor.g = c2.y;
    this.stick.endColor.b = c2.z;

    this.stick.geometry.colorsNeedUpdate = true;
  };
}
